package cn.edu.nju.ws.sview.views;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;

import cn.edu.nju.ws.sview.cache.URITypeCache;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.thirdparty.FalconObjectSearch;
import cn.edu.nju.ws.sview.views.data.EntityManagement;
import cn.edu.nju.ws.sview.views.data.EntityManagement.Item;
import cn.edu.nju.ws.sview.views.data.ViewEditing;
import cn.edu.nju.ws.sview.views.data.ViewEditing.DataMemberItem;




public class CustomCollection extends Entity {

	public CustomCollection(String name, String groupName,String lang, HashSet<URIResource> members) {
		super(name,groupName,lang,members);
	}
	
	/*tmp collection构造方式*/
	public CustomCollection(String name, String lang, HashSet<URIResource> members) {
		super(name,-1,lang,members);
	}
	
    /**
     * 得到集合根据同指等价关系合并后的成员
     * need to be checked: 当其他组的成员使用这个集合进行编辑时
     * @param collectionID
     * @return
     */
	public static HashSet<EntityItem> getReducedMembersOfCollection(int collectionID){
		HashSet<EntityItem> result = new HashSet<EntityItem>();
//        HashSet<Integer> originMembers = Entity.getMembersByEntityId(collectionID);
//        if(Entity.isTmpCollection(Entity.COLLECTION, collectionID)){
//        	String etype = Entity.URI_ENTITY_Str;
//        	for(Integer eid:originMembers){
//        		EntityItem item = new EntityItem(etype,eid);
//        		result.add(item);
//        	}
//        }else{
//        	int groupID = Entity.getGroupIDOfEntity(collectionID);
//        	for(Integer id:originMembers){
//        		HashSet<Item> items = EntityManagement.getInstance().getRelatedMyGroupEntity(Entity.URI_ENTITY, id, groupID, "");
//        		Item item = null;
//        		for(Item mitem:items){
//        			item = mitem;
//        			break;
//        		}
//        		if(item==null){
//        			String etype = Entity.URI_ENTITY_Str;
//        			EntityItem eitem = new EntityItem(etype,id);
//            		result.add(eitem);
//        		}else{
//        			item.getEType();
//        		}
//        	}
//        }
		return result;
	}
	
	/**
	 * 集合类型的计算
	 * 目前采用成员类型的并作为其类型，
	 * @param members
	 * @return
	 */
	public HashSet<Integer> computeCollectionClassTypes( HashSet<URIResource> members){
		HashSet<Integer> types = new HashSet<Integer>();
		for(URIResource resource:members){
			int uid = resource.getID();
			try {
				types.addAll(URITypeCache.getInstance().getTypes(uid));
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		return types;
	}
	
	/**
	 * 根据可用的datamembers计算topNum个datamember,
	 * 可以用于初始时的集合datamember浏览
	 * @param alldatamembers. 所有可用的datamember
	 * @param topNum. 要返回的datamember个数
	 * @return. 第一个元素dmtype,第二个元素dmid
	 */
	public static ArrayList<DataMemberItem> getTopDataMembers(HashSet<DataMemberItem> alldatamembers,int topNum){
		ArrayList<DataMemberItem> result = new ArrayList<DataMemberItem>();
		if(alldatamembers.size()<=topNum){
			result.addAll(alldatamembers);
			return result;
		}
		//先看看dmInCollection_visit，看看推荐数目是否足够了
		ArrayList<DataMemberItem> part = getTopDataMembersInHistory(alldatamembers, topNum);
		result.addAll(part);
		
		//没有足够的日志，强行推荐
		if(result.size()<topNum){
			int remainNum = topNum-result.size();
			HashSet<DataMemberItem> visited = new HashSet<DataMemberItem>(result);
			alldatamembers.removeAll(visited);
			ArrayList<DMItem> originDMs = new ArrayList<DMItem>();
			for(DataMemberItem item:alldatamembers){
				if(item.getDMType()==DataMember.URI_DATAMEMBER){
					int desNum = FalconObjectSearch.getPropertyDescribingRDFDocNum(item.getDMID());
					DMItem  dmitem = new DMItem(item,desNum);
					originDMs.add(dmitem);
				}
			}
			Collections.sort(originDMs);
			for(int i=0;i<remainNum;i++){
				result.add(originDMs.get(i).item);
			}
		}
			
		return result;
	}
	
	/**
	 * !!!!!!!need to be checked if merge uri entity
	 * @param lang
	 * @param etype. 
	 * @param eid
	 * @param isInner
	 * @param classID
	 * @return
	 */
	public static HashSet<DataMemberItem> getAvailableDMsOfCollection(String lang,int collectionID, boolean isInner,int classID){
		HashSet<DataMemberItem> itemset = new HashSet<DataMemberItem>();
		itemset.addAll(ViewEditing.getForwardDM(lang, Entity.COLLECTION,collectionID,true));
		itemset.addAll(ViewEditing.getBackwardDM(lang, Entity.COLLECTION,collectionID,true));
		itemset.addAll(ViewEditing.getCustomDM(lang, isInner, classID,true));
		return itemset;
	}      

	/**
	 * 根据历史，对于可用的datamembers计算topNum个datamember,
	 * 可以用于初始时的集合datamember浏览
	 * @param alldatamembers. 所有可用的datamember
	 * @param topNum. 要返回的datamember个数
	 * @return. 第一个元素dmtype,第二个元素dmid
	 */
	private static ArrayList<DataMemberItem> getTopDataMembersInHistory(HashSet<DataMemberItem> alldatamembers,int topNum){
		ArrayList<DataMemberItem> result = new ArrayList<DataMemberItem>();
		//map存储具有更多信息的item
		HashMap<DataMemberItem,DataMemberItem> map = new HashMap<DataMemberItem,DataMemberItem>();
		//先看看dmInCollection_visit，看看推荐数目是否足够了
		Connection con = DBConnectionFactory.getConnection();
		try {
			StringBuffer buffer= new StringBuffer();
			buffer.append("select member_type,member_id,inverse from dmInCollection_visit where ");
			int count = 0;
			buffer.append("( ");
			for(DataMemberItem  item:alldatamembers){
				map.put(item, item);
				count++;
				int dmtype = item.getDMType();
				int dmid = item.getDMID();
				boolean inverse = item.getInverse();
				String tmp = "( member_type="+dmtype+" and member_id="+dmid+" and inverse="+inverse+" )";
				buffer.append(tmp);
				if(count<alldatamembers.size())
					buffer.append(" or ");
			}
			buffer.append(" ) ");
			buffer.append("group by member_type,member_id,inverse order by sum(times_total) desc limit "+topNum);
			PreparedStatement stmt = con.prepareStatement(buffer.toString());
			ResultSet rs = stmt.executeQuery();
			while(rs.next()){
				int dmtype = rs.getInt("member_type");
				int dmid = rs.getInt("member_id");
				boolean inverse = rs.getBoolean("inverse");
				DataMemberItem item = new DataMemberItem(dmtype,dmid,inverse);
				result.add(map.get(item));
			}
			rs.close();
			stmt.close();
			con.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}
	
	private static class DMItem implements Comparable<DMItem>{
		DataMemberItem item;
		int num;
		DMItem(DataMemberItem item,int num){
			this.item = item;
			this.num = num;
		}
		@Override
		public int compareTo(DMItem o) {
			// TODO Auto-generated method stub
			if(this.num>o.num){
				return -1;
			}else if(this.num<o.num){
				return 1;
			}else
				return 0;
		}
	}
}

